<style scoped>
.home{
  height: 80vh;
}
</style>

<template>
  <div class="home">
    
    <Card>
      <h2> 任务切换 </h2>
      <RadioGroup @on-change='changeTask' v-model="type">
          <Radio label="month"></Radio>
          <Radio label="agendaWeek"></Radio>
          <Radio label="agendaDay"></Radio>
      </RadioGroup>
    </Card>
    
    <full-calendar :events='events' :config='config' ref="full" >
    </full-calendar>


  
  </div>
</template>

<script>
import "fullcalendar/dist/fullcalendar.css";
import Vue from 'vue'
import $ from 'jquery' 
/**
 * 样式对象转字符
 * @param { object } style
 * @return { string } styleString
 */

export function toStyleStr(style) {
    return Object.entries(style).reduce((acc, [key, value]) => `${acc}${key}:${value};`, '')
}


export default {
  name: 'Home',
 
  data(){

    const _this = this    
     return {
        type: 'month',
        vmNodeSign: 'vm-node',
        dataMap: {},
        visibal: true,
        dropdownVisible: false,
        modalVisibal: false,
        events: [],
        config: {
          buttonText: { today: "今天", month: "月", week: "周", day: "日" },
          locale: "zh-cn",
          editable: false,
          selectable: false,
          eventLimit: 4, 
          allDaySlot: false, 
          defaultView: "month",

          /**
           * 任务渲染后插入自定义vue节点
           * @summary 根据当前所处状态[ view.type 月 周 日 ]  构建不同的展示 
           */
          eventAfterRender: function(event, element, view ) {

            // 当前显示状态, 月 周 日
            const type = view.type
            const target = element[0]
            const baseStyle = `${target.style.cssText} color: #fff; border-radius: 4px; padding: 0 4px;` // 基础容器样式
            const innerStyle = `width: ${target.offsetWidth}px; height: ${target.offsetHeight}px;` // 内容容器, 保证poptip 被内容完全撑开
            const eleInnerHTML = target.innerHTML // 原内容结构 - 非必须，可以自定义内容替换
            const vmNodeSign = _this.vmNodeSign // 移除标记

            const title = event.title
            const content = event.content
            const source = _this.dataMap[title]

            console.log('event >>>', source)
            
            // 月构建
            function month(){
              return {
                data(){
                  return {}
                },
                render(){
                  return (
                    <div class={vmNodeSign} style={ baseStyle }>
                      <Poptip trigger="hover" title={ title } content={content}>
                        <div domPropsInnerHTML={ eleInnerHTML } style={ innerStyle } >
                        </div>
                      </Poptip>
                    </div>
                  )
                }
              }
            }


            /**
             * 周构建
             * @summary 切换到 周 日项时 需要补全定位样式
             */
            function agendaWeek(){
              return {
                data(){
                    return {}
                  },
                render(){

                  const headStyle = toStyleStr({
                    padding: '6px 2px',
                    display: 'flex',
                    'justify-content': 'space-between',
                    'align-items': 'center',
                    'border-bottom': '1px solid #eee'
                  })
                  const itemStyle = toStyleStr({
                    'padding-top': '4px'
                  })

                  const descStyle = toStyleStr({
                    margin: '6px 0 0 0',
                    padding: '4px',
                    'border-radius': '4px',
                    background: '#fff',
                    color: '#333'
                  }) 
                  
                  return (
                    <div class={vmNodeSign}  style={ `${baseStyle};position: absolute;` }>

                      <div style={ headStyle }> { source.departureName } <Icon type="md-arrow-round-forward" /> { source.destinationName } </div>
                      <div style={itemStyle}> <Icon type="md-car" /> { source.taskDriverCars[0]['carNo'] } </div>
                      <div style={itemStyle}> 
                          <p style='font-size: 12px'> 始: { source.exceptStartTime } </p>
                          <p style='font-size: 12px'> 终: { source.exceptEndTime } </p>
                      </div>
                      <div style={descStyle}> 
                          <p style='font-size: 12px'> 
                          { source.taskDriverCars[0].carDesc }
                          </p>
                      </div>

                    </div>
                  )
                }
              }
            }

            // 日构建
            function agendaDay(){
              return {
                data(){
                  return {}
                },
                render(){
                  return (
                    <div class={vmNodeSign}  style={ `${baseStyle};position: absolute;` }>
                      <div domPropsInnerHTML={ eleInnerHTML } style={ innerStyle } >
                      </div>
                    </div>
                  )
                }
              }
            }

            const buildFactory = {
              month,
              agendaWeek,
              agendaDay,
            }
            

            /**
             * 加载构建
             */
            _this.$nextTick(() => {
              new Vue(buildFactory[type]()).$mount(target)
            })
          
          }
        }

      }
    },

  methods: {

    clearVmNode(){
      $(`.${this.vmNodeSign}`).remove()
    },

    // 模拟数据切换
    async changeTask(){

      const data = {
        month: [
          {
            
            departureName: '火锅山',
            destinationName: '雪糕地',
            taskCode: 220,
            taskDriverCars: [ { carNo: '粤110', carDesc: '小宝' } ],
            status: '运行中',
            exceptStartTime: '2020-03-19 10:00:00',
            exceptEndTime: '2020-03-19 14:00:00',
            color: 'orange'
            
          } 
        ],

        agendaWeek: [
          {
            
            departureName: '那美克',
            destinationName: '波利斯',
            taskCode: 220,
            taskDriverCars: [ { carNo: '粤110', carDesc: '小宝' } ],
            status: '运行中',
            exceptStartTime: '2020-03-19 20:00:00',
            exceptEndTime: '2020-03-19 23:00:00',
            color: 'pink'
            
          } 
        ],

        agendaDay: [
          {
            
            departureName: '宝宝山',
            destinationName: '妖怪岛',
            taskCode: 220,
            taskDriverCars: [ { carNo: '粤110', carDesc: '小宝' } ],
            status: '运行中',
            exceptStartTime: '2020-03-19 0:00:00',
            exceptEndTime: '2020-03-19 10:00:00',
            color: 'gray'
            
          } 
        ]
      }

      const res = await this.getData(data[this.type])

      // 切换events时清空vm节点
      this.clearVmNode()

      // 构建任务及数据映射
      const { events, dataMap } = res.reduce( (acc, item) => {

        const eventConf = {
          title: `${item.departureName} ~ ${item.destinationName}`,
          content: `${item.taskCode} ~ ${item.taskDriverCars[0]['carNo']} ~ ${item.taskDriverCars[0]['carDesc']} ~ ${item.status} `,
          start: item.exceptStartTime,
          end: item.exceptEndTime,
          color: item.color,
          source: item
        }

        return {
          events: [ ...acc.events, eventConf ],
          dataMap: { ...acc.dataMap, [eventConf.title]: item }
        }
          
      }, { events:[], dataMap: {} })

      this.events = events
      this.dataMap = dataMap

    },

    // 模拟请求
    getData(data){
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(data)
        }, 1000);
      })
    },
  },

  created(){
    this.changeTask()
  }

}
</script>
